package apii.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import apii.server.ServerThings;

/**
 * 
 * @author evgeniy
 * 
 */
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 * 
	 */
	public LoginServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Map<String, String[]> map = request.getParameterMap();
		try {
			UserRequesterData urd = ServletUtils.extractRequesterData(request
					.getSession(false));
			if (map.keySet().isEmpty()) {
				if (urd.sessionId == null) { // anonymous
					ServletUtils.generateLoginForm(response.getWriter(), "",
							"", false);
				} else {
					if (urd.logged) {
						// user is logged but still invades login page
						// let us show his home page
						if (urd.role == UserRequesterData.ROLE_PROF) {
							ServletUtils.redirectToUrl(response, "/prof");
						} else if (urd.role == UserRequesterData.ROLE_STUD) {
							ServletUtils.redirectToUrl(response, "/stud");
						} else {
							System.out.println("role: " + urd.role);
							throw new Error();
						}
					} else {
						// the user is not logged, but has session
						// let us prompt him login and password
						if (urd.userId == UserRequesterData.UNKNOWN_ID) {
							// the user was logged some time before, but server
							// does not remember him
							ServletUtils.generateLoginForm(
									response.getWriter(), "", "", false);
						} else {
							ServletUtils.generateLoginForm(
									response.getWriter(),
									Integer.toString(urd.userId), urd.password,
									false);
						}
					}
				}
			} else {
				ServletUtils.redirectToIllegalPage(response);
			}
		} catch (SQLException ex) {
			ServletUtils.redirectToErrorPage(response, ex.getMessage());
			ex.printStackTrace();
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try {
			UserRequesterData urd = ServletUtils.extractRequesterData(request
					.getSession(false));

			if ((urd.sessionId == null) || !urd.logged) {
				// give him a chance to login
				String enteredId = request
						.getParameter(ServletUtils.LOGIN_NAME);
				String enteredPassword = request
						.getParameter(ServletUtils.PASSWORD_NAME);

				if ((enteredId != null) && (enteredPassword != null)) {
					try {
						int userRole = verifyUser(enteredId, enteredPassword);
						if (userRole == UserRequesterData.USER_INCORRECT) {
							ServletUtils.generateLoginForm(
									response.getWriter(), enteredId, "", true);
						} else {
							HttpSession session = request.getSession(true);
							ServletUtils.tieSession(session,
									Integer.parseInt(enteredId));

							// redirect
							String redirectLocation;
							if (userRole == UserRequesterData.ROLE_PROF) {
								redirectLocation = "/prof";
							} else if (userRole == UserRequesterData.ROLE_STUD) {
								redirectLocation = "/stud";
							} else {
								ServletUtils.redirectToErrorPage(response,
										"Internal server error");
								throw new Error();
							}
							ServletUtils.redirectToUrl(response,
									redirectLocation);
						}
					} catch (SQLException ex) {
						ServletUtils.redirectToErrorPage(response,
								ex.getMessage());
					}
				}
			} else {
				// do not let logged users to login
				// redirect on the home page
				if (urd.role == UserRequesterData.ROLE_PROF) {
					ServletUtils.redirectToUrl(response, "/prof");
				} else if (urd.role == UserRequesterData.ROLE_STUD) {
					ServletUtils.redirectToUrl(response, "/stud");
				} else {
					throw new Error();
				}
			}

		} catch (SQLException ex) {
			ServletUtils.redirectToErrorPage(response, ex.getMessage());
			ex.printStackTrace();
		}
	}

	private int verifyUser(String login, String password) throws SQLException {
		int result;
		if (ServletUtils.validateNumber(login)
				&& ServletUtils.validateIdentifier(password)) {
			Connection c = ServerThings.getThings().getConnection();
			// TODO: make prepared statement
			Statement s = c.createStatement();
			ResultSet userRS = s
					.executeQuery("SELECT apii.users.role, apii.users.password FROM apii.users "
							+ "WHERE apii.users.user_id = '" + login + "'");

			if (!userRS.next()) {
				result = UserRequesterData.USER_INCORRECT;
			} else {
				// check password
				if (userRS.getString(2).equals(password)) {
					result = userRS.getInt(1);
				} else {
					result = UserRequesterData.USER_INCORRECT;
				}
			}
			c.close();
		} else {
			result = UserRequesterData.USER_INCORRECT;
		}
		return result;
	}
}
